import { computed, signal } from "@preact/signals"
import dayjs from "dayjs"
import { createLogger } from "@/utils/logger"
import { signalWithStorage } from "@/utils/signal_utils"
import { PayloadFormatter } from "@/utils/format"

const logger = createLogger("ApiSignals")

const dataSiganlProfile = signalWithStorage<Partial<ApiTypes.Fetcher.Result.UserProfile>>(
    {},
    "user_profile",
)
const dataSiganlKyc = signalWithStorage<Partial<Kyc.Data.Detail>>({}, "kyc")

const ApiSignals = {
    dataSiganlProfile,
    dataSiganlKyc,
}

export default ApiSignals

const kycSourceData = computed(() => {
    const profile = dataSiganlProfile.value
    const kyc = dataSiganlKyc.value
    const kycStatus = kyc.status ?? "unset"

    const status: Kyc.Status = (() => {
        const profileFirstName = profile.realName?.firstName
        const profileLastName = profile.realName?.lastName

        const isProfileRealNameComplete = profileFirstName && profileLastName

        if (isProfileRealNameComplete && kycStatus === "unset") {
            return "basic_passed"
        }

        return kyc.status ?? "unset"
    })()

    const output = {
        profile: dataSiganlProfile.value,
        kyc: {
            ...kyc,
            status,
        },
    }

    logger.debug("kycSourceData", output)
    return output
})

const kycDataFetched = computed(() => {
    return !!dataSiganlProfile.value && !!dataSiganlKyc.value
})

const kycExpiredAt = computed(() => {
    const createdAtDayjs = dayjs(dataSiganlProfile.value?.created_at)
    const endDayjs = createdAtDayjs.add(3, "day")
    return endDayjs
})

const hoursAfterMemberCreated = computed(() => {
    const createdAtDayjs = dayjs(dataSiganlProfile.value?.created_at)
    const diff = dayjs().diff(createdAtDayjs, "hours")
    return diff
})

const hoursAfterKycCreated24Hours = computed(() => {
    const createdAtDayjs = dayjs(dataSiganlKyc.value?.created_at)
    const diff = dayjs().diff(createdAtDayjs, "hours")
    return diff > 24
})

const hoursAfterKycCreated48Hours = computed(() => {
    const createdAtDayjs = dayjs(dataSiganlKyc.value?.created_at)
    const diff = dayjs().diff(createdAtDayjs, "hours")
    return diff > 48
})

const hoursAfterKycCreated72Hours = computed(() => {
    const createdAtDayjs = dayjs(dataSiganlKyc.value?.created_at)
    const diff = dayjs().diff(createdAtDayjs, "hours")
    return diff > 72
})

const kycLeftSeconds = computed(() => {
    const expiredAt = kycExpiredAt.value
    if (!expiredAt) return 0
    const diff = expiredAt.diff(dayjs(), "seconds")
    return diff > 0 ? diff : 0
})

const kycOcrStatus = computed(() => {
    const kyc = dataSiganlKyc.value
    if (!kyc.ocr_status) return 0
    return kyc.ocr_status
})

const isUserLogin = computed(() => {
    if (dataSiganlProfile.value?.username) {
        return true
    }
    return false
})

export const searchParamsSignal = signal(new URLSearchParams(window.location.search))
const kycOcrCallbackParams = computed(() => {
    const params = searchParamsSignal.value
    const payloadEncoded = params.get("payload")

    if (!payloadEncoded) {
        return null
    }

    try {
        const payload = PayloadFormatter.decode(
            payloadEncoded,
        ) as unknown as Kyc.Data.OcrCallbackParams
        const success = params.get("success") === "true"

        return {
            ...payload,
            success,
        }
    } catch (error) {
        logger.debug("解析 OCR 回調參數失敗", error)
        return null
    }
})

export const BusinessSignals = {
    kycSourceData,
    kycExpiredAt,
    hoursAfterMemberCreated,
    hoursAfterKycCreated24Hours,
    hoursAfterKycCreated48Hours,
    hoursAfterKycCreated72Hours,
    kycLeftSeconds,
    kycDataFetched,
    kycOcrStatus,
    kycOcrCallbackParams,
    isUserLogin,
}
